#include "crc16.h"

crc16::crc16()
{

}

/*******************************************************************************
* Function Name  : culCalcCRC.
* Description    : CRC16子程序.
* Input          : 数据、计算值.
* Output         : None.
* Return         : 计算后的CRC值.
*******************************************************************************/
unsigned short crc16::culCalcCRC(unsigned char crcData, unsigned short  crcReg)
{
    unsigned char  i;

    for (i = 0; i < 8; i++)
    {
        if (((crcReg & 0x8000) >> 8) ^ (crcData & 0x80))
            crcReg = (crcReg << 1) ^ 0x8005;
        else
            crcReg = (crcReg << 1);

        crcData <<= 1;
    }

    return crcReg;
}

/*******************************************************************************
* Function Name  : CRC_Cal.
* Description    : 计算CRC16数据组函数.
* Input          : 数据、长度.
* Output         : None.
* Return         : 计算后的CRC值.
*******************************************************************************/
unsigned short crc16::CRC_Cal(const unsigned char * buf,unsigned int len)
{
    unsigned short checksum = 0xffff;
    unsigned int Cnt = 0;
    for(Cnt = 0; Cnt < len; Cnt++)
    {
        checksum = culCalcCRC(*(buf+Cnt), checksum);
    }

    return checksum;
}

/*******************************************************************************
* Function Name  : Check_CRC.
* Description    : 校验buf中的crc是否正确
* Input          : buf数据、len长度.
* Output         : None.
* Return         : crc值正确返回true,否则false.
*******************************************************************************/
bool crc16::Check_CRC(const unsigned char * buf, unsigned int len)
{
    if (!buf)
        return false;

    if (buf[len - 1] != 0x23)
        return false; //最后一字节不是0x23则表示不完整的数据帧，校验失败返回false

    unsigned short oldcrcval = buf[len -3];
    oldcrcval = (oldcrcval << 8) | buf[len -2];

    unsigned short crcval = CRC_Cal(buf, len - 3);
    return (oldcrcval == crcval) ? true : false;
}

